package cli;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import java.util.Map;

import actions.Indexing;
import actions.Searching;
import omero.ServerError;
import exception.DataException;
import exception.MatlabException;
import exception.ServerConnectionException;

import javax.swing.*;

/**
 * Syntax as follows:
 * 	StartCli -u -p -a -r -d 
 * 	-h	help
 * 	-u 	omero username
 * 	-p	omero password
 * 	-a index|search	
 * 			Which action to perform on the omero server:
 * 			index datasetid
 * 			search datasetId roiId
 *    	datasetId required for indexing and searching actions
 * 	    roiId  roiId is required for search action
 
 * 
 * @author Peter Kuijpers
 *
 */
public class StartCli {

	private static int INDEX = 1;
	private static int SEARCH = 2;
	private static int ALGORITHMS = 3;
	private static int action;
	private static int port = 4064;
	
	private static String host;
	private static String userName;
	private static String pwd;
	private static String actionStr;
	private static String roiIdStr;
	private static String datasetIdStr;
	private static Long roiId, datasetId;
	private static String algoName;
	
	static JFrame display = new JFrame("Mips-Server");
	static JTextArea displayText = new JTextArea();
	static JScrollPane displayScroll = new JScrollPane(displayText);
	
	
	/**
	 * @param args
	 * @throws ServerConnectionException 
	 * @throws ServerError 
	 * @throws DataException 
	 */
	public static void main(String[] args) throws ServerConnectionException, ServerError, DataException {
		display.add(displayScroll);
		display.setSize(400, 600);
		display.setVisible(true);
		
		int len = args.length;
	
		String wrongSyntax = "Wrong number of parameters.";
		String hStr = "StartCli -h host -u user -p password -a action\n";
		hStr += "\t-h\t omero hostname\n";
		hStr += "\t-u\t omero username\n";
		hStr += "\t-p\t omero password\n";
		hStr += "\t-a index|search|algorithms   Action to perform:\n";
		hStr += "\t\t   index datasetId   For indexing the images so that they can be searched\n";
		hStr += "\t\t   search datasetId roiId algorithmName   Search the images in the dataset for region_of_interest, with algorithm\n" ;
		hStr += "\t\t   algorithms   Returns a list of available matlab algorithms that can be used in a search\n" ;
		
		Map<String, String> env = System.getenv();
		Iterator it = env.entrySet().iterator();
		while( it.hasNext() ) {
			Map.Entry pairs  = (Map.Entry)it.next();
			System.out.println( pairs.getKey() +  " = " + pairs.getValue() );
			displayText.append( pairs.getKey() +  " = " + pairs.getValue() + "\n");
			
		}
		
		if (len == 0 ) {
			System.out.println( hStr );
			displayText.setText( hStr + "\n");
			return;
		}
		
		int cnt = 0;

		if ( len < 8 ) {
			System.out.println("Wrong number of parameters" + len);
			System.out.println( wrongSyntax );
			displayText.setText("Wrong number of parameters" + len + "\n");
			displayText.append(wrongSyntax +"\n" );
			return;
		}
		if ( args[cnt++].equals("-h" )) {
			host = args[cnt++];
		}
		if ( args[cnt++].equals("-u") ) {
			userName = args[cnt++];
		} else {
			System.out.println("username argument not found " + cnt);
			System.out.println( wrongSyntax );
			displayText.setText("username argument not found " + cnt + "\n");
			displayText.append(wrongSyntax +"\n" );
			return;
		}
		if ( args[cnt++].equals("-p" )) {
			pwd = args[cnt++];
		} else {
			System.out.println("password argument not found " + cnt);
			System.out.println( wrongSyntax );
			displayText.setText("password argument not found " + cnt + "\n");
			displayText.append(wrongSyntax +"\n" );
			return;
		}
		if ( args[cnt++].equals("-a") ) {
			actionStr = args[cnt++];
	
			if ( actionStr.equals( "index") ) { 
				if ( len == 9 ) {
					datasetIdStr = args[cnt++];
					action = INDEX;
				} else {
					System.out.println("Wrong action argument" );
					System.out.println( wrongSyntax );
					displayText.setText( "Wrong action argument"  + "\n" );
					displayText.append(wrongSyntax +"\n" );
					return;
				}
			} else if ( actionStr.equals( "search" )) {
				if ( len == 11 ) {
					datasetIdStr = args[cnt++];
					roiIdStr = args[cnt++];
					algoName = args[cnt];
					action = SEARCH;
				} else {
					System.out.println("Wrong action argument" );
					System.out.println( wrongSyntax );
					displayText.setText("Wrong action argument"  + "\n");
					displayText.append(wrongSyntax +"\n" );
					return;
				}
			} else if ( actionStr.equals( "algorithms" )) {
				action = ALGORITHMS;
			} else {
				// wrong argument
				System.out.println("Wrong action argument" );
				System.out.println( wrongSyntax );
				displayText.setText("Wrong action argument"  + "\n");
				displayText.append(wrongSyntax +"\n" );
				return;
			}
			
		} else {
			System.out.println("Wrong action argument" );
			System.out.println( wrongSyntax );
			displayText.setText("Wrong action argument"  + "\n");
			displayText.append(wrongSyntax +"\n" );
			return;
		}
		
		try {
			if ( action == SEARCH ) {
				datasetId = Long.parseLong( datasetIdStr );
				roiId = Long.parseLong( roiIdStr );
				//algoName is already assigned
				System.out.println( StartCli.printDetails() );
				displayText.append(StartCli.printDetails() + "\n");
				
				searching( roiId, datasetId, algoName );
			} else if ( action == INDEX ) {
				datasetId = Long.parseLong( datasetIdStr );
				System.out.println( StartCli.printDetails() );
				displayText.append(StartCli.printDetails() + "\n");
				indexing( datasetId );
			} else if ( action == ALGORITHMS ) {
			//	getAlgorithms();
				System.out.println( StartCli.printDetails() );
				displayText.append(StartCli.printDetails() + "\n");

			} else {
				System.out.println("Wrong action argument" );
				System.out.println( wrongSyntax );
				displayText.setText("Wrong action argument"  + "\n");
				displayText.append(wrongSyntax +"\n" );
				return;
			}
				
			
		} catch ( NumberFormatException e ) {
			System.out.println( wrongSyntax );
			displayText.append(wrongSyntax +"\n" );
		}
		
		//indexing( 1364 );
		
		// search for roi in dataset
		//searching( 155, 1360);
//		searching(  107 , 1 );
		//
//		searching( 152, 152 );
		
	}
	
	/**
	 * Do the indexing of the dataset
	 * @param datasetId 
	 * @throws DataException 
	 */
	private static void indexing( long datasetId ) throws DataException {
		try {
			OmeroServer.open(host, port, userName, pwd );
			System.out.println("Indexing images in dataset: " + datasetId );
			displayText.append("Indexing images in dataset: " + datasetId + "\n");
			Indexing.start( datasetId );
		} catch (ServerConnectionException e) {
			System.out.println("Unable to connect to server: " + e.getMessage() );
			displayText.append("Unable to connect to server: " + e.getMessage() + "\n");
			e.printStackTrace();
		} catch (ServerError e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MatlabException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		OmeroServer.close();
	}
	
	/**
	 * Search images in the dataset
	 * @param datasetId
	 * @throws DataException 
	 */
	private static void searching(long roiId, long datasetId, String algoName) throws DataException {
		//search images
		System.out.println("Start searching images");
		displayText.append("Start searching images\n");
		try {
		OmeroServer.open( host, port, userName, pwd );
		Searching.start( roiId, datasetId, algoName );
		System.out.println("Finished searching images");
		displayText.append("Finished searching images\n");
		} catch( ServerConnectionException e ) {
			System.out.println("Unable to connect to server: " + e.getMessage() );
			displayText.append("Unable to connect to server: " + e.getMessage() + "\n" );
		} catch (ServerError e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MatlabException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		OmeroServer.close();
	}
	private static String printDetails() {
		String str = "Hostname: " + host;
		str += "\nPort: " + port;
		str += "\nUsername: " + userName;
		str +="\nPasword length" + pwd.length();
		if ( action == INDEX ) {
			str += "\nAction: Indexing";
			str += "\ndatasetId " + datasetId;
		} else if ( action == SEARCH ){
			str += "\nAction: Searching";
			str += "\ndatasetId: " + datasetId;
			str +="\nroiId: " + roiId;
			str += "\nalgorithm name: " + algoName;
		} else if ( action == ALGORITHMS ) {
			str += "\nAction: Algorithms";
		}
		return str;
	}
}		

		
	

